package cn.walls1717.juc.future;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * 基础使用
 *
 * @author walls1717
 * @create 2022/12/09 13:24
 **/
@Slf4j
public class CompletableFutureUseDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(3);

        // CompletableFuture的默认线程池是自动关闭的，在main线程执行完成之后，线程池自动关闭。
        CompletableFuture.supplyAsync(() -> {
            log.info(Thread.currentThread().getName() + "come in ...");
            int result = ThreadLocalRandom.current().nextInt(10);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (result > 1) {
                int i = 10/0;
            }
            log.info("1s后拿到结果");
            return result;
        // 当业务执行完成后，执行如下，v表示前一步的返回值，e表示前一步执行时出现的异常。
        }, executor).whenComplete((v, e) -> {
            if (e == null) {
                log.info("成功拿到结果 -> {}", v);
            }
        // 如果第一步业务出现异常，会直接走到这个方法，e表示异常，可以在出现异常之后做一些业务处理。
        }).exceptionally(e -> {
            e.printStackTrace();
            log.info("业务出现异常 -> {} | {}", e.getCause(), e.getMessage());
            return null;
        });

        log.info(Thread.currentThread().getName() + "线程执行其它业务");

        executor.shutdown();

        // TimeUnit.SECONDS.sleep(3);
    }

    /**
     * 效果与FutureTask一样，都是异步执行任务。
     *
     * @throws Exception .
     */
    private static void m1() throws Exception {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            log.info(Thread.currentThread().getName() + "come in ...");
            int result = ThreadLocalRandom.current().nextInt(10);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("1s后拿到结果");
            return result;
        });

        log.info(Thread.currentThread().getName() + "线程执行其它业务...");

        log.info(future.get().toString());
    }
}
